package controller

import (
	"encoding/json"
	"log"
	"net/http"
	"strconv"
	"time"

	"github.com/gin-gonic/gin"
	uuid "github.com/satori/go.uuid"

	"order-publisher/dao"
	"order-publisher/model"
	"order-publisher/utils"
)

// ChooseGift 提交抢礼物订单
// @Summary 抢礼物
// @Description 抢礼物
// @Tags 用户接口
// @Accept json
// @Produce  json
// @Param orderInfo body model.OrderInfo true "订单信息"
// @Success 200 {object} model.Result "{"msg": "该订单成功加入消息队列"}"
// @Failure 500 {object} model.Result "{"msg": "请求数据为空/该订单未成功加入消息队列"}"
// @Router /orderapi/chooseGift [post]
func ChooseGift(c *gin.Context) {
	// 解析请求
	var orderInfo model.OrderInfo
	switch c.Request.Method {
	case http.MethodPost:
		dec := json.NewDecoder(c.Request.Body)
		err := dec.Decode(&orderInfo)
		if err != nil {
			log.Println(err.Error())
			c.Writer.WriteHeader(http.StatusInternalServerError)
			return
		}
	}

	// 检验所传字段是否为空
	if orderInfo.GiftID == 0 {
		model.Response(c.Writer, false, 500, "GiftID为空", nil)
		return
	}
	if orderInfo.Name == "" || orderInfo.StudentID == "" || orderInfo.Address == "" ||
		orderInfo.AddressDetail == "" || orderInfo.Phone == "" || orderInfo.UID == "" {
		model.Response(c.Writer, false, 500, "用户数据不全", nil)
		return
	}

	// 把用户信息存入user表
	user_id, is_success, err := dao.AddUserInfo(&orderInfo)
	if !is_success || err != nil {
		model.Response(c.Writer, false, 500, "新增用户信息失败", map[string]string{"err": err.Error()})
		return
	}
	// model.Response(c.Writer, true, 200, "新增用户信息成功", map[string]string{"uid": orderInfo.UID, "name": orderInfo.Name, "student_id": orderInfo.StudentID, "address": orderInfo.Address + orderInfo.AddressDetail, "phone_number": orderInfo.Phone})

	// 用uuid唯一标志orderID
	orderID := uuid.NewV4().String()

	// 创建生成订单的时间
	timeStr := time.Now().Format("2006-01-02 15:04:05")

	// 生成订单
	order := &model.Order{
		OrderID: orderID,
		UID:     orderInfo.UID,           // uid：用户ID
		UserID:  strconv.Itoa((user_id)), // user表的主键id，不是用户id(uid)
		GiftID:  orderInfo.GiftID,
		SubTime: timeStr,
	}

	// 将订单加入rabbitMQ
	_, err = utils.SendOrder(order)
	if err != nil {
		model.Response(c.Writer, false, 500, "该订单未成功加入消息队列", map[string]string{"err": err.Error()})
	}
	model.Response(c.Writer, true, 200, "该订单成功加入消息队列", map[string]string{"order_id": orderID, "user_id": order.UserID, "gift_id": strconv.Itoa(order.GiftID), "submit_time": order.SubTime})
}

// OrderCheck 检查该用户是否成功抢到过该礼物
// @Summary 检查该用户是否成功抢到过该礼物
// @Description 成功抢过该礼物的用户，不能再次下该礼物的订单
// @Tags 用户接口
// @Accept json
// @Produce  json
// @Param orderCheckInfo body model.OrderCheckInfo true "订单检查信息"
// @Success 200 {object} model.Result "{"msg": "该用户未抢过该礼物，可以进入后续抢礼物界面"}"
// @Failure 500 {object} model.Result "{"msg": "该用户已抢过该礼物"}"
// @Router /orderapi/orderCheck [post]
func OrderCheck(c *gin.Context) {
	// 解析请求
	var orderCheckInfo model.OrderCheckInfo
	switch c.Request.Method {
	case http.MethodPost:
		dec := json.NewDecoder(c.Request.Body)
		err := dec.Decode(&orderCheckInfo)
		if err != nil {
			log.Println(err.Error())
			c.Writer.WriteHeader(http.StatusInternalServerError)
			return
		}
	}

	// 检验所传字段是否为空
	if orderCheckInfo.GiftID == 0 {
		model.Response(c.Writer, false, 500, "GiftID为空", nil)
		return
	}
	if orderCheckInfo.UID == "" {
		model.Response(c.Writer, false, 500, "uid为空", nil)
		return
	}

	// 查数据库中是否有该用户抢该礼物的成功订单
	is_exist, err := dao.GetOrderByUIDAndGiftID(orderCheckInfo.UID, orderCheckInfo.GiftID)
	if is_exist {
		model.Response(c.Writer, false, 500, "该用户已抢过该礼物", nil)
		return
	}
	model.Response(c.Writer, false, 200, "该用户未抢过该礼物，可以进入后续抢礼物界面", map[string]string{"err": err.Error()})
}

// GetOrdersByOrderID 通过OrderID查询某个订单
// @Summary 通过OrderID获取某个订单
// @Description 通过OrderID获取某个订单
// @Tags 用户接口
// @Accept json
// @Produce  json
// @Param orderID body model.Order true "订单ID"
// @Success 200 {object} model.Result "{"msg": "成功获取订单"}"
// @Failure 500 {object} model.Result "{"msg": "获取订单失败"}"
// @Router /orderapi/getOrderByOrderID [post]
func GetOrderByOrderID(c *gin.Context) {
	// 解析请求，获取OrderID
	var order model.Order
	switch c.Request.Method {
	case http.MethodPost:
		dec := json.NewDecoder(c.Request.Body)
		err := dec.Decode(&order)
		if err != nil {
			model.Response(c.Writer, false, 500, "解析失败", map[string]string{"err": err.Error()})
			log.Println(err.Error())
			c.Writer.WriteHeader(http.StatusInternalServerError)
			return
		}
	}

	// 通过OrderID获取用户订单消息
	orderWithGiftAndUserInfo, err := dao.GetOrderByOrderID(order.OrderID)
	if err != nil {
		model.Response2(c.Writer, false, 500, "获取订单失败", map[string]interface{}{"err": err})
		return
	}
	model.Response2(c.Writer, true, 200, "成功获取订单", map[string]interface{}{"Order": orderWithGiftAndUserInfo})
}

// GetOrdersByUID 查询某个用户的订单
// @Summary 通过UID获取某个用户的所有订单
// @Description 通过UID获取某个用户的所有订单
// @Tags 用户接口
// @Accept json
// @Produce  json
// @Param UID body model.UserInfo true "用户ID"
// @Success 200 {object} model.Result "{"msg": "成功获取用户订单信息"}"
// @Failure 500 {object} model.Result "{"msg": "获取用户订单消息失败"}"
// @Router /orderapi/getOrdersByUID [post]
func GetOrdersByUID(c *gin.Context) {
	// 解析请求，获取UID
	var userInfo model.UserInfo
	switch c.Request.Method {
	case http.MethodPost:
		dec := json.NewDecoder(c.Request.Body)
		err := dec.Decode(&userInfo)
		if err != nil {
			model.Response(c.Writer, false, 500, "解析失败", map[string]string{"err": err.Error()})
			log.Println(err.Error())
			c.Writer.WriteHeader(http.StatusInternalServerError)
			return
		}
	}

	// 通过UID获取用户订单消息
	orderWithGiftAndUserInfos, err := dao.GetOrdersByUID(userInfo.UID)
	if err != nil {
		model.Response2(c.Writer, false, 500, "获取用户订单消息失败", map[string]interface{}{"err": err})
		return
	}
	model.Response2(c.Writer, true, 200, "成功获取用户订单信息", map[string]interface{}{"Orders": orderWithGiftAndUserInfos})
}

// GetAllResult 查询所有订单（管理员接口）
// @Summary 查询所有订单
// @Description 查询所有订单
// @Tags 管理员接口
// @Produce  json
// @Success 200 {object} model.Result2 "{"msg": "成功获取订单信息"}"
// @Failure 500 {object} model.Result2 "{"msg": "获取订单消息失败"}"
// @Router /orderapi/getAllOrders [get]
func GetAllOrders(c *gin.Context) {
	orderWithGiftAndUserInfos, err := dao.GetOrders()
	if err != nil {
		model.Response2(c.Writer, false, 500, "获取订单消息失败", map[string]interface{}{"err": err})
		return
	}
	model.Response2(c.Writer, true, 200, "成功获取订单信息", map[string]interface{}{"Orders": orderWithGiftAndUserInfos})
}
